package com.toptech.downloadmanager;

import android.app.ProgressDialog;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;

import com.toptech.downloadmanager.ToolUtils.ContantsUtils;
import com.toptech.downloadmanager.ToolUtils.LitePalUtils;
import com.toptech.downloadmanager.callback.ConnectServiceCallback;
import com.toptech.downloadmanager.callback.DownloadCallback;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zhengshaorui on 2017/3/10.
 */

public class DownloadClient {
    private static final String TAG = "zsr";
    private static final int UPDATE_LOADING_INFO = 1;
    private static final int UPDATE_SUCCESS_INFO = 2;
    private static final int UPDATE_FAIL_INFO = 3;
    private Context mContext;
    private IRemoteService  mBinder;
    private List<FileInfo> mFileInfos = new ArrayList<FileInfo>();
    private FileInfo mFileInfo;
    private volatile static  DownloadClient mDownloadClient;
    Handler mDevider = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg) {
            switch(msg.what){
                case UPDATE_LOADING_INFO:
                    mCallback.getTaskInfoStatus(mFileInfo);
                    break;

                case UPDATE_SUCCESS_INFO:

                    break;
            }

            super.handleMessage(msg);
        }
    };

    private DownloadClient(Context context){
        this.mContext = context;
        bindService();
        IntentFilter filter = new IntentFilter();
        filter.addAction(ContantsUtils.DOWNLOADERROR);
        filter.addAction(ContantsUtils.DOWNLOADSUCCESS);
        mContext.registerReceiver(downloadReceiver,filter);
    }

   public static DownloadClient getInstance(Context context){
       if (mDownloadClient == null){
           synchronized (DownloadClient.class){
               if (mDownloadClient == null){
                   mDownloadClient = new DownloadClient(context);
               }
           }
       }
       return mDownloadClient;
   }


    /**
     * 以回调的时候获取服务端的数据反馈
     * 注意，这里是在子线程的；
     */
    private ICallback mServerCallback = new ICallback.Stub() {
        @Override
        public void getLoadingTaskInfo(FileInfo fileinfo) throws RemoteException {
            //Log.d("rachel", "getLoadingTaskInfo: "+fileinfo.getFileName()+" "+fileinfo.getProgress());
            if (fileinfo != null){
                mFileInfo = fileinfo;
              //  mDevider.sendEmptyMessage(UPDATE_LOADING_INFO);
                mDevider.obtainMessage(UPDATE_LOADING_INFO,fileinfo).sendToTarget();
            }
        }


    };

    /**
     * 获取广播数据
     */
    BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(ContantsUtils.DOWNLOADERROR)){
                FileInfo fileInfo = intent.getParcelableExtra("fileinfo");
                String errorMsg = intent.getStringExtra("errorMsg");
                int errorCode = intent.getIntExtra("errorCode",-1);
                mCallback.taskFail(errorCode,errorMsg,fileInfo);
            }

            if (action.equals(ContantsUtils.DOWNLOADSUCCESS)){
                FileInfo fileInfo = intent.getParcelableExtra("fileinfo");
                mCallback.taskSuccess(fileInfo);
            }


        }
    };


    public int getServerTaskNum() {
        int count = 0;
        if (mBinder != null) {
            try {
                count = mBinder.getTaskMax();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return count;
    }

    /**
     * 连接服务器，并提供回调接口
     * @param callback
     */
    public void connectServer(final ConnectServiceCallback callback){
        final ProgressDialog mDialog = new ProgressDialog(mContext);
        mDialog.setCanceledOnTouchOutside(true);
        mDialog.setCancelable(true);
        mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mDialog.setTitle("正在连接服务器，请稍后");
        mDialog.show();

        mDevider.postDelayed(new Runnable() {
            @Override
            public void run() {
                mDialog.dismiss();
                if (mBinder != null) {
                    callback.success();
                    try {
                        mBinder.registerCallback(mServerCallback);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
                else {
                    callback.fail();
                }

            }
        },2000);
    }

    /**
     * 暂停所有的任务
     */
    public List<FileInfo> pauseAllTask(){
        List<FileInfo> fileinfos = new ArrayList<>();
        try {
            if (mBinder != null) {
                fileinfos = mBinder.setAllTaskPause();
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return fileinfos;
    }

    /**
     * 开始所有的任务
     */
    public List<FileInfo> reStartAllTask(){
        List<FileInfo> fileinfos = new ArrayList<>();
        try {
            if (mBinder != null) {
                fileinfos = mBinder.setAllTaskStart();
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return fileinfos;
    }


    /**
     * 暂停任务
     * @param fileinfo
     */
    public void pauseTask(FileInfo fileinfo){
        if (mBinder != null){
            try {

                fileinfo.setBtnstatus(ContantsUtils.PAUSE);
                mBinder.setFileTaskStatus(fileinfo);

            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 任务重新开始
     */
    public void reStartTask(FileInfo fileinfo){
        if (mBinder != null){
            try {

                fileinfo.setBtnstatus(ContantsUtils.START);
                mBinder.setFileTaskStatus(fileinfo);

            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 判断任务是否暂停了
     * @param fileinfo
     * @return
     */
    public boolean isTaskPause(FileInfo fileinfo){
        if (fileinfo.getBtnstatus() == ContantsUtils.PAUSE)
            return true;
        else
            return false;
    }

    /**
     * 开始下载并回调下载信息
     */



    private DownloadCallback mCallback;
    public void startDownload(List<FileInfo> fileinfos,DownloadCallback callback){
        try {
            if (mBinder != null) {

                mBinder.addTaskList(fileinfos);
                this.mCallback = callback;

                mDevider.sendEmptyMessage(UPDATE_LOADING_INFO);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }


    /**
     * 添加一个新任务
     * @param config
     * @return
     */
    public List<FileInfo> addNewTask(DownloadConfigGuration config){
        for (int i = 0; i < mFileInfos.size(); i++) {   //先清空
            mFileInfos.remove(i);
        }
        try {
            List<TaskInfo> mTaskInfos = mBinder.getAllTask();
            Log.d(TAG, "addNewTask: "+mTaskInfos);



            if (mTaskInfos != null){
                for (TaskInfo taskInfo : mTaskInfos){
                    FileInfo fileInfo = new FileInfo();
                    fileInfo.setFileName(taskInfo.getFilename());
                    fileInfo.setApkurl(taskInfo.getFileurl());
                    fileInfo.setProgress(taskInfo.getFileprogress());
                    fileInfo.setFiledownsize(taskInfo.getFiledownsize());
                    fileInfo.setFilesize(taskInfo.getFilesize());
                    fileInfo.setThreadCount(taskInfo.getThreadcount());
                    fileInfo.setBtnstatus(ContantsUtils.START);

                    mFileInfos.add(fileInfo);
                }
            }
            checkDataRepeat(mTaskInfos,config);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

        return mFileInfos;
    }

    /**
     * 添加多个任务
     * @param configs
     * @return
     */
    public List<FileInfo> addMulTasks(List<DownloadConfigGuration> configs,int mode){
        mFileInfos.clear(); //清空以前的数据
        try {
            List<TaskInfo> taskInfos = mBinder.getAllTask(); //获取远程任务

            if (taskInfos != null){
                for (TaskInfo taskInfo : taskInfos){
                    FileInfo fileInfo = new FileInfo();
                    fileInfo.setId(taskInfo.getId());
                    fileInfo.setFileName(taskInfo.getFilename());
                    fileInfo.setApkurl(taskInfo.getFileurl());
                    fileInfo.setProgress(taskInfo.getFileprogress());
                    fileInfo.setFiledownsize(taskInfo.getFiledownsize());
                    fileInfo.setFilesize(taskInfo.getFilesize());
                    fileInfo.setThreadCount(taskInfo.getThreadcount());
                    fileInfo.setBtnstatus(ContantsUtils.START);
                    fileInfo.setPriority(taskInfo.getPriority());
                    mFileInfos.add(fileInfo);
                }
                for (DownloadConfigGuration config : configs) {
                    checkDataRepeat(taskInfos, config);
                }
            }else{ //远程没有任务，全部自己下载
                for (DownloadConfigGuration config : configs)
                    mFileInfos.add(addData(config,0));
            }

        } catch (RemoteException e) {
            e.printStackTrace();
        }


        List<FileInfo> filelists = new ArrayList<>();
        switch(mode){
            case ContantsUtils.GETNEEDDOWNLOADTASK:
                for (FileInfo fileinfo : mFileInfos){
                    if (fileinfo.getProgress() >=0 && fileinfo.getProgress() < 100 ){
                        filelists.add(fileinfo);
                    }else {
                        continue;
                    }
                }
                return  filelists;

            case ContantsUtils.GETFINISHEDTASK:
                for (FileInfo fileinfo : mFileInfos){
                    if (fileinfo.getProgress() == 100 ){
                        filelists.add(fileinfo);
                    }else {
                        continue;
                    }
                }
                return  filelists;

        }
        return mFileInfos;
    }

    /**
     * 删除一个任务
     * @param fileInfo
     */
    public void deleteTask(FileInfo fileInfo){
        if (mBinder != null){
            try {
                mBinder.deleteTask(fileInfo);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 防止软件下一次启动时，任务重复添加的问题
     * @param taskinfos
     * @param config
     */
    private void checkDataRepeat(List<TaskInfo> taskinfos,DownloadConfigGuration config){

        //标示去掉用id的方式，全部采用url。
       /* boolean istaskexsits = LitePalUtils.isTaskInfoExsits(config.getFileurl());
        TaskInfo taskInfo = null;
        long id = 0;
        if (!istaskexsits) { //如果这个任务，数据库中并不存在
             taskInfo = new TaskInfo(0,config.getFilename(),config.getFileurl(),
                    0,null,null,config.getThreadcount(),config.getPriority());
            taskInfo.saveThrows();//保存任务的信息到数据库
        }else{
            id = LitePalUtils.getTaskId(config.getFileurl());
        }*/
        /*if (taskinfos.size() == 0){//服务端还没有数据
           // mFileInfos.add(addData(config,taskInfo.getId()));

        }else{
            for (int i = 0; i < taskinfos.size(); i++) {
                if (taskinfos.get(i).getFileurl().equals(config.getFileurl())) {
                    return;
                }

            }
        }*/

        for (int i = 0; i < taskinfos.size(); i++) {
            if (taskinfos.get(i).getFileurl().equals(config.getFileurl())) {

                return;
            }


        }
        mFileInfos.add(addData(config,0));
        // mFileInfos.add(addData(config,id));

        Log.d(TAG, "checkDataRepeat: "+taskinfos.size()+" "+mFileInfos.size());

    }


    //下载的路径由服务端决定
    private FileInfo addData(DownloadConfigGuration configGuration,long id){
        FileInfo info  = new FileInfo(id+1,configGuration.getFileurl(),configGuration.getFilename(),
                null,null,0,configGuration.getThreadcount(),0,"0",
                "0", ContantsUtils.FILE_NOT_DOWNLOAD,ContantsUtils.START,0,null,
                configGuration.getPriority());
        return info;
    }


    /**
     * 连接远程服务端
     */
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBinder = IRemoteService.Stub.asInterface(service);
            Log.d(TAG, "onServiceConnected: ");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBinder = null;
        }
    };

    /**
     * 绑定远程服务
     */
    private void bindService() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.toptech.downloadmanager",
                "com.toptech.downloadmanager.RemoteService"));
        mContext.bindService(intent,conn, Service.BIND_AUTO_CREATE);
    }

    public void unBinderServer()  {
        mContext.unbindService(conn);
        mContext.unregisterReceiver(downloadReceiver);

        if (mBinder != null){
            try {
                mBinder.unregisterCallback(mServerCallback);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }
}
